
package com.simple.mqtt.server.session;

import com.simple.mqtt.common.domain.TopicFilter;
import com.simple.mqtt.common.task.MqttPendingPublish;
import com.simple.mqtt.common.task.MqttPendingQos2Publish;
import com.simple.mqtt.server.domain.Subscribe;

import java.util.List;

/**
 * MQTT会话管理器接口，负责管理客户端会话信息
 * 主要功能包括：
 * - 管理客户端订阅关系
 * - 管理消息发布状态(PendingPublish/PendingQos2Publish)
 * - 生成和管理消息ID
 * - 会话生命周期管理
 * <p>
 * 设计上不封装MqttSession实体，方便redis等集群处理
 *
 * @author L.cm
 */
public interface IMqttSessionManager {

    /**
     * 添加订阅存储
     *
     * @param topicFilter topicFilter
     * @param clientId    客户端 Id
     * @param mqttQoS     MqttQoS
     */
    public void addSubscribe(TopicFilter topicFilter, String clientId, int mqttQoS);

    /**
     * 添加订阅存储
     *
     * @param topicFilter topicFilter
     * @param clientId    客户端 Id
     * @param mqttQoS     MqttQoS
     */
    default void addSubscribe(String topicFilter, String clientId, int mqttQoS) {
        this.addSubscribe(new TopicFilter(topicFilter), clientId, mqttQoS);
    }

    /**
     * 删除订阅
     *
     * @param topicFilter topicFilter
     * @param clientId    客户端 Id
     */
    public void removeSubscribe(String topicFilter, String clientId);

    /**
     * 查找订阅 qos 信息
     *
     * @param topicName topicName
     * @param clientId  客户端 Id
     * @return 订阅存储列表
     */
    public Byte searchSubscribe(String topicName, String clientId);

    /**
     * 查找订阅信息
     *
     * @param topicName topicName
     * @return 订阅存储列表
     */
    public List<Subscribe> searchSubscribe(String topicName);

    /**
     * 获取设备订阅
     *
     * @param clientId clientId
     * @return 订阅列表
     */
    public List<Subscribe> getSubscriptions(String clientId);

    /**
     * 添加发布过程存储
     *
     * @param clientId       clientId
     * @param messageId      messageId
     * @param pendingPublish MqttPendingPublish
     */
    public void addPendingPublish(String clientId, int messageId, MqttPendingPublish pendingPublish);

    /**
     * 获取发布过程存储
     *
     * @param clientId  clientId
     * @param messageId messageId
     * @return MqttPendingPublish
     */
    public MqttPendingPublish getPendingPublish(String clientId, int messageId);

    /**
     * 删除发布过程中的存储
     *
     * @param clientId  clientId
     * @param messageId messageId
     */
    public void removePendingPublish(String clientId, int messageId);

    /**
     * 添加发布过程存储
     *
     * @param clientId           clientId
     * @param messageId          messageId
     * @param pendingQos2Publish MqttPendingQos2Publish
     */
    public void addPendingQos2Publish(String clientId, int messageId, MqttPendingQos2Publish pendingQos2Publish);

    /**
     * 获取发布过程存储
     *
     * @param clientId  clientId
     * @param messageId messageId
     * @return MqttPendingQos2Publish
     */
    public MqttPendingQos2Publish getPendingQos2Publish(String clientId, int messageId);

    /**
     * 删除发布过程中的存储
     *
     * @param clientId  clientId
     * @param messageId messageId
     */
    public void removePendingQos2Publish(String clientId, int messageId);

    /**
     * 生成消息 Id
     *
     * @param clientId clientId
     * @return messageId
     */
    public int getPacketId(String clientId);

    /**
     * 判断是否存在 session
     *
     * @param clientId clientId
     * @return 是否存在 session
     */
    public boolean hasSession(String clientId);

    /**
     * 标记 session 超时时间
     *
     * @param clientId             clientId
     * @param sessionExpirySeconds sessionExpirySeconds
     * @return 是否成功
     */
    public boolean expire(String clientId, int sessionExpirySeconds);

    /**
     * 激活 session，标记 expire 的 session 为永久
     *
     * @param clientId clientId
     * @return 是否成功
     */
    public boolean active(String clientId);

    /**
     * 清除 session
     *
     * @param clientId clientId
     */
    public void remove(String clientId);

    /**
     * 清理
     */
    public void clean();

}
